#include "stm32_uart.h"
//#include "Log.h"

static char Tx_Buffer[FORMAT_BUFFER_SIZE]={0}; //格式化缓存

void User_USARTx_Init(RxHandle_t *rxHandle, uint8_t uart_id)
{
	assert_param(rxHandle != NULL);
	UARTx_Printf(rxHandle->huart,"USART%d initialization successful\n\r",uart_id);
	User_UART_Receive_Start(rxHandle);
}


void User_UART_Receive_Start(RxHandle_t *rxHandle)
{
	assert_param(rxHandle != NULL);
	rxHandle->write = !rxHandle->write;
	if(rxHandle->huart->hdmarx != NULL)
	{
		HAL_UARTEx_ReceiveToIdle_DMA(rxHandle->huart,
									 &rxHandle->Msg[rxHandle->write].data[0],
									 RXMSG_BUFFER_SIZE);
		__HAL_DMA_DISABLE_IT(rxHandle->huart->hdmarx, DMA_IT_HT);
	}
	else
	{
		HAL_UARTEx_ReceiveToIdle_IT(rxHandle->huart,
									&rxHandle->Msg[rxHandle->write].data[0],
									RXMSG_BUFFER_SIZE);
	}
}

uint8_t *UART_GetRxData(RxHandle_t *hrx)
{
	return hrx->Msg[!hrx->write].data;
}

uint16_t UART_GetRxSize(RxHandle_t *hrx)
{
	return hrx->Msg[!hrx->write].size;
}

void TxHandle_TxCpltCallback(TxHandle_t *htx)
{
	uint8_t *pdata;
	uint16_t size;
	if (htx->huart->hdmatx->State != HAL_DMA_STATE_READY)
		return;
	if (htx->sendsize)
	{
		cQueue_Skip(&htx->cQ, htx->sendsize);
		htx->sendsize = 0;
	}
	size = cQueue_GetReadPtrMargin(&htx->cQ);
	pdata = cQueue_GetReadAdr(&htx->cQ);
	if (size)
	{
		htx->sendsize = size;
		HAL_UART_Transmit_DMA(htx->huart, pdata, size);
	}
}

void RxHandle_RxEventCallback(RxHandle_t *hrx, uint16_t size)
{
	hrx->rxCpltFlag = 1;
	hrx->Msg[hrx->write].size = size;
	User_UART_Receive_Start(hrx);
}

void UART_RxHandle_CreateStatic(UART_HandleTypeDef *huart, RxHandle_t *hrx)
{
	assert_param(hrx != NULL && huart != NULL);
	hrx->huart = huart;
	hrx->write = 0;
}

void UART_TxHandle_CreateStatic(UART_HandleTypeDef *huart, TxHandle_t *htx, 
							  uint8_t *dataBuf, uint16_t bufSize)
{
	assert_param(htx != NULL && huart != NULL && dataBuf != NULL);
	htx->huart = huart;
	cQueue_Create_Static(&htx->cQ, dataBuf, sizeof(uint8_t), bufSize);
}

int UARTx_Printf(UART_HandleTypeDef *huart, const char *fmt, ...)
{
    uint16_t cnt;
    va_list ap;
    va_start(ap, fmt);
    cnt = vsnprintf((char *)Tx_Buffer, FORMAT_BUFFER_SIZE, fmt, ap);
    va_end(ap);
    HAL_UART_Transmit(huart, (uint8_t *)Tx_Buffer, cnt, 0xffff);
    // RTT_Logs(Tx_Buffer);
    return cnt;
}
int UARTx_Print(UART_HandleTypeDef *huart, const char *str)
{
    uint16_t len = strlen(str);
    HAL_UART_Transmit(huart, (uint8_t *)str, len, 0xffff);
    // RTT_Logs(str);
    return len;
}
int UARTx_Printn(UART_HandleTypeDef *huart, uint8_t *pdata, int len)
{
    HAL_UART_Transmit(huart, (uint8_t *)pdata, len, 0xffff);
    // Logs(pdata);
	// Log("[size:%d]\n",len);
    return len;
}

int Queue_Printf(TxHandle_t *htx, const char *fmt, ...)
{
    uint32_t cnt;
    va_list ap;
    va_start(ap, fmt);
    cnt = vsnprintf((char *)Tx_Buffer, FORMAT_BUFFER_SIZE, fmt, ap);
	va_end(ap);
	return Queue_Printn(htx, (uint8_t*)Tx_Buffer, cnt);
}

int Queue_Print(TxHandle_t *htx, const char *str)
{
    uint32_t cnt = strlen(str);
	return Queue_Printn(htx, (uint8_t*)str, cnt);
}

int Queue_Printn(TxHandle_t *htx, uint8_t *pdata, size_t cnt)
{

	if (htx->huart->hdmatx == NULL) return 0; //该串口没得DMA
	if (htx->huart->gState != HAL_UART_STATE_READY) //DMA正忙
	{
		Logs("[Log]DMA Busy send, push to Queue\n");
		if(cQueue_Pushs(&htx->cQ, pdata, cnt) != CQUEUE_OK)//添加到发送队列
		{
			/* 队列已满处理 */
			Logs("[Log]FIFO Busy\n");
			return 0;
		}
	}
	else 
	{
		HAL_UART_Transmit_DMA(htx->huart, (uint8_t *)pdata, cnt);
	}

	return cnt;
}


